# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.8 |Anaconda custom (64-bit)| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: helpers\http_clients\scan_api\__init__.py
__author__ = "Attila Gerendi (Sanyi)"
import logging, requests, requests.exceptions
from api.classes.scan.auto import *
from helpers.http_clients.exceptions import (
    RequestError,
    AuthException,
    HTTP400,
    HTTP500,
    HTTP404,
    HTTP409,
    RequestParsingError,
    HTTP403,
)
from scanners.scan_app.errors import *
from settings_provider import settings

_logger = logging.getLogger("helpers.http_clients.scan_api")


class ScanApiClient:
    def __init__(
        self,
        endpoint,
        scanning_app,
        api_key=None,
        headers=None,
        ssl_verify=False,
        request_timeout=None,
    ):
        self.endpoint = endpoint
        self.api_key = api_key
        self.scanning_app = scanning_app
        if ssl_verify is False:
            self.ssl_verify = False
        else:
            if ssl_verify is True:
                ssl_ca_bundle_path = settings.get("ssl_ca_bundle_path", None)
                if ssl_ca_bundle_path:
                    self.ssl_verify = ssl_ca_bundle_path
                else:
                    self.ssl_verify = None
                self.session = requests.session()
                if headers is None:
                    self.headers = dict()
                if api_key is not None:
                    self.headers["X-Auth"] = api_key
                self.request_timeout = request_timeout
                self.base_url = endpoint + "/" + self.scanning_app

    def _do_request(self, method, url, headers=None, filename=None, **kwargs):
        if headers is None:
            headers = self.headers
        else:
            headers.update(self.headers)
        if self.request_timeout is not None:
            kwargs["timeout"] = self.request_timeout
        if filename:
            kwargs["stream"] = True
        try:
            result = method(url=url, verify=self.ssl_verify, headers=headers, **kwargs)
        except Exception as e:
            raise RequestError(str(e))

        if result.status_code == 204:
            return
        if result.status_code == 200:
            pass
        if filename:
            with open(filename, "wb") as (f):
                for chunk in result.iter_content(chunk_size=1024):
                    if chunk:
                        f.write(chunk)

            return filename
            try:
                result = result.json()
            except Exception:
                _logger.error("HTTP200 json parse error " + result.text)
                raise RequestParsingError()

            return result
        else:
            if result.status_code == 201:
                try:
                    result = result.json()
                except Exception:
                    _logger.error("HTTP201 json parse error " + result.text)
                    raise RequestParsingError()

                return result
            if result.status_code == 401:
                raise AuthException()
            else:
                if result.status_code == 404:
                    try:
                        result = result.json()
                    except Exception:
                        _logger.error("HTTP404 json parse error " + result.text)
                        raise RequestParsingError()

                    raise HTTP404(result=result)
                else:
                    if result.status_code == 400:
                        try:
                            result = result.json()
                        except Exception:
                            _logger.error("HTTP400 json parse error " + result.text)
                            raise RequestParsingError()

                        _logger.warning(result)
                        raise HTTP400(result=result)
                    else:
                        if result.status_code == 403:
                            try:
                                result = result.json()
                            except Exception:
                                _logger.error("HTTP403 json parse error " + result.text)
                                raise RequestParsingError()

                            _logger.warning(result)
                            raise HTTP403(result=result)
                        else:
                            if result.status_code == 409:
                                try:
                                    result = result.json()
                                except Exception:
                                    _logger.error(
                                        "HTTP409 json parse error " + result.text
                                    )
                                    raise RequestParsingError()

                                _logger.warning(result)
                                raise HTTP409(result=result)
                            else:
                                if result.status_code == 500:
                                    try:
                                        result = result.json()
                                    except Exception:
                                        _logger.error(
                                            "HTTP500 json parse error " + result.text
                                        )
                                        raise RequestParsingError()

                                    _logger.warning(result)
                                    raise HTTP500(result=result)
                                else:
                                    _logger.warning(
                                        "HTTP%s not handled, %s",
                                        result.status_code,
                                        result.text,
                                    )
                                    raise RequestParsingError()

    def file_download(self, path, filename, headers=None):
        return self._do_request(
            self.session.get,
            url=self.base_url + path,
            headers=headers,
            filename=filename,
        )

    def get_request(self, path, headers=None):
        return self._do_request(
            self.session.get, url=self.base_url + path, headers=headers
        )

    def delete_request(self, path, headers=None):
        return self._do_request(
            self.session.delete, url=self.base_url + path, headers=headers
        )

    def post_request(self, path, data, headers=None):
        return self._do_request(
            self.session.post, url=self.base_url + path, headers=headers, json=data
        )

    def patch_request(self, path, data, headers=None):
        return self._do_request(
            self.session.patch, url=self.base_url + path, headers=headers, json=data
        )

    def get_job_status(self, job_identifier_list):
        try:
            result = self.post_request("/get_job_status", job_identifier_list.to_dict())
        except HTTP404 as e:
            raise JobNotFound() from e

        return ClsJobStatuses(**result)

    def abort_job(self, job_identifier):
        try:
            return self.post_request("/abort_job", job_identifier.to_dict())
        except HTTP404 as e:
            r = getattr(e, "result", None)
            if isinstance(r, dict):
                if r.get("code") == ApiErrors.SA_JOB_NOT_FOUND:
                    raise JobNotFound() from e
            raise

    def pause_job(self, job_identifier):
        try:
            return self.post_request("/pause_job", job_identifier.to_dict())
        except HTTP404 as e:
            r = getattr(e, "result", None)
            if isinstance(r, dict):
                if r.get("code") == ApiErrors.SA_JOB_NOT_FOUND:
                    raise JobNotFound() from e
            raise

    def start_job(self, job):
        try:
            return self.post_request("/start_job", job.to_dict())
        except HTTP409 as e:
            if e.result["code"] == ApiErrors.SA_NO_MORE_WORKER_SLOTS:
                raise NoMoreWorkerSlots() from e
            if e.result["code"] == ApiErrors.SA_DUPLICATE_JOB_ID:
                raise DuplicateJobId() from e
            raise

    def delete_job(self, job_identifier):
        try:
            return self.post_request("/delete_job", job_identifier.to_dict())
        except HTTP404 as e:
            raise JobNotFound() from e

    def get_worker_status(self):
        result = self.get_request("/worker")
        return ClsWorkerStatus(**result)

    def check_connection(self):
        result = self.get_request("/worker/connect")
        return ClsWorkerConnectionInfo(**result)
